﻿using RegexBuilder.Interfaces;
using System.Text;

namespace RegexBuilder
{
    internal class RegexBasePattern : IRegexStringProvider
    {
        public RegexBasePattern()
        {
            Pattern = "";
            IsGreedy = true;
        }
        /// <summary>
        /// 匹配基元
        /// </summary>
        public string Pattern { get; set; }
        /// <summary>
        /// 是否贪婪，默认为true
        /// </summary>
        public bool IsGreedy { get; set; }

        /// <summary>
        /// 最小匹配次数
        /// </summary>
        public uint? LeastTimes { get; set; }
        /// <summary>
        /// 最大匹配次数
        /// </summary>
        public uint? MostTimes { get; set; }

        /// <summary>
        /// 标记是否Pattern已经是完整正则
        /// </summary>
        public bool IsRawRegexString { get; set; }
        /// <summary>
        /// 正向肯定预查
        /// </summary>
        public IRegexStringProvider? LookAheadPositiveAssert { get; set; }
        /// <summary>
        /// 正向否定预查
        /// </summary>
        public IRegexStringProvider? LookAheadNegativeAssert { get; set; }
        /// <summary>
        /// 反向肯定预查
        /// </summary>
        public IRegexStringProvider? LookBehindPositiveAssert { get; set; }
        /// <summary>
        /// 反正否定预查
        /// </summary>
        public IRegexStringProvider? LookBehindNegativeAssert { get; set; }



        public string ToRegexString()
        {
            if (IsRawRegexString)
            {
                return Pattern;
            }
            StringBuilder sb = new StringBuilder();
            if (string.IsNullOrEmpty(Pattern))
            {
                return string.Empty;
            }
            sb.Append(Pattern);
            if (
                (LeastTimes != null || MostTimes != null)
                && !(LeastTimes == 1 && MostTimes == 1)
                )
            {
                if ((LeastTimes == 0 || LeastTimes == null) && MostTimes == 1)
                {
                    sb.Append("?");
                }
                else if (MostTimes == null && LeastTimes == 1)
                {
                    sb.Append("+");
                }
                else if (LeastTimes == 0 && MostTimes == null)
                {
                    sb.Append("*");
                }
                else if (LeastTimes == MostTimes && LeastTimes > 0)
                {
                    sb.Append($"{{{LeastTimes}}}");
                }
                else
                {
                    sb.Append($"{{{LeastTimes ?? 0},{MostTimes}}}");
                }
                if (IsGreedy == false)
                {
                    sb.Append("?");
                }
            }
            if (LookBehindPositiveAssert != null)
            {
                var result = LookBehindPositiveAssert.ToRegexString();
                if (result.Length > 0)
                    sb.Append($"(?<={result})");
            }
            if (LookBehindNegativeAssert != null)
            {
                var result = LookBehindNegativeAssert.ToRegexString();
                if (result.Length > 0)
                    sb.Append($"(?<!{result})");
            }
            if (LookAheadPositiveAssert != null)
            {
                var result = LookAheadPositiveAssert.ToRegexString();
                if (result.Length > 0)
                    sb.Append($"(?={result})");
            }
            if (LookBehindNegativeAssert != null)
            {
                var result = LookBehindNegativeAssert.ToRegexString();
                if (result.Length > 0)
                    sb.Append($"(?!{result})");
            }
            return sb.ToString();
        }
    }
}


